(ns clj-8583.crypt
  (:import (javax.crypto Cipher SecretKeyFactory)
           (javax.crypto.spec DESKeySpec IvParameterSpec))
  (:use [clj-8583.binary]
        [clj-8583.long-util]))

;DES/ECB/NoPadding
(defn crypto-bytes
  [src-bytes key-bytes transformatinon crypt-mode]
  (let [cipher (Cipher/getInstance transformatinon)
        key-spec (DESKeySpec. key-bytes)
        key-factory (SecretKeyFactory/getInstance "DES")
        secret-key (.generateSecret key-factory key-spec)]
    (.init cipher crypt-mode secret-key)
    (.doFinal cipher src-bytes)))

(defn encrypt-bytes
  [src-bytes key-bytes transformatinon crypt-mode]
  (let [cipher (Cipher/getInstance transformatinon)
        key-sepc (DESKeySpec. key-bytes)
        key-factory (SecretKeyFactory/getInstance "DES")
        ;para-spec (IvParameterSpec. (byte-array 8))
        secret-key (.generateSecret key-factory key-sepc)]
    ;(.init cipher crypt-mode secret-key para-spec)
    (.init cipher crypt-mode secret-key)
    (.doFinal cipher src-bytes)))


;1234567890ABCDEF1234567890ABCDEF
;D8678C53805DD3D3

; (def mac-key "D8678C53805DD3D3D8678C53805DD3D3")
; (def main-key "1234567890ABCDEF1234567890ABCDEF")
;(def mac-key "2222222222222222ABCDEF1234567890")
(def main-key "821DA3E1F05042ED3033B817A96F4800")
(defn decrypt-mac-key
  [mac-key main-key]
  (let [i-mac-key mac-key
        i-main-first  (subs main-key 0 16)
        i-main-second (subs main-key 16)
        transformatinon "DES/ECB/NoPadding"]
    (if (= i-main-second i-main-first)
      (subs (bytes-to-hex
        (crypto-bytes
          (byte-array (hex-to-bytes i-mac-key))
          (byte-array (hex-to-bytes i-main-first))
          transformatinon 2)) 0 16)
      (let [imac-key (byte-array (hex-to-bytes i-mac-key))
            imain1   (byte-array (hex-to-bytes i-main-first))
            imain2   (byte-array (hex-to-bytes i-main-second))]
        (bytes-to-hex
          (crypto-bytes
            (crypto-bytes
              (crypto-bytes imac-key imain1 transformatinon 2)
              imain2 transformatinon 1)
            imain1 transformatinon 2))))))

;(defn xor-des
;  [src-hex mac-key]
;  (let [src-bytes (map #(byte %) src-hex)
;        src-part (partition 8 src-bytes)]
;    (reduce #(bit-xor (bytes-to-long (crypto-bytes ())))))

(defn main-compute
  [elements lvalue mac-key]
  (if (empty? elements)
    (long-to-bytes lvalue)
    (recur
      (rest elements)
      (bytes-to-long
        (crypto-bytes
          (long-to-bytes
            (bit-xor lvalue (bytes-to-long (byte-array (first elements)))))
          mac-key
          "DES/ECB/NoPadding"
          1))
      mac-key)))

; (defn main-compute
;   [elements lvalue key]
;   (if (empty? elements)
;     (long-to-bytes lvalue)
;     (recur
;       (rest elements)
;       (bytes-to-long
;         (crypt-)))))

(defn xor-des
  [src-bytes mac-key]
  (let [src-part (partition 8 (concat src-bytes (byte-array 7)))
        mac-bytes (byte-array (hex-to-bytes mac-key))]
    (main-compute src-part 0 mac-bytes)))




; (defn judge-domain
;   [bitmap-array]
;   (#{2 3 4 7 11 18 25 28 32 33 38 39 41 42 90 102 103}))
